import 'package:intl/intl.dart' as intl;
import 'package:jvtd_flutter_utils/jvtd_flutter_utils.dart';

/// 日期格式
enum DateFormat {
  DEFAULT, //年月日时分秒毫秒
  NORMAL, //年月日时分秒
  YEAR, //年
  MONTH, //月
  DAY, //日
  YM, //年月
  YMD, //年月日
  YMDHM, //年月日时分
  MD, //月日
  MDHM, //月日时分
  HMS, //时分秒
  HM, //时分
}

/// 时间区间类型
enum DateIntervalType {
  day, //日
  week, //星期
  month, //月
  year, //年
}

/// 日期工具类
class DateUtil {
  static const String _DATE_LOCALE = 'zh';

  static const Map<DateFormat, String> _dateFormats = {
    DateFormat.DEFAULT: 'yyyy-MM-dd HH:mm:ss.SSS',
    DateFormat.NORMAL: 'yyyy-MM-dd HH:mm:ss',
    DateFormat.YEAR: 'yyyy',
    DateFormat.MONTH: 'MM',
    DateFormat.DAY: 'dd',
    DateFormat.YM: 'yyyy-MM',
    DateFormat.YMD: 'yyyy-MM-dd',
    DateFormat.YMDHM: 'yyyy-MM-dd HH:mm',
    DateFormat.MD: 'MM-dd',
    DateFormat.MDHM: 'MM-dd HH:mm',
    DateFormat.HMS: 'HH:mm:ss',
    DateFormat.HM: 'HH:mm',
  };

  static const Map<DateFormat, String> _zhDateFormats = {
    DateFormat.DEFAULT: 'yyyy年MM月dd日 HH时mm分ss秒SSS毫秒',
    DateFormat.NORMAL: 'yyyy年MM月dd日 HH时mm分ss秒',
    DateFormat.YEAR: 'yyyy年',
    DateFormat.MONTH: 'MM月',
    DateFormat.DAY: 'dd日',
    DateFormat.YM: 'yyyy年MM月',
    DateFormat.YMD: 'yyyy年MM月dd日',
    DateFormat.YMDHM: 'yyyy年MM月dd日 HH时mm分',
    DateFormat.MD: 'MM月dd日',
    DateFormat.MDHM: 'MM月dd日 HH时mm分',
    DateFormat.HMS: 'HH时mm分ss秒',
    DateFormat.HM: 'HH时mm分',
  };

  /// 基于字符串获取时间
  ///
  /// [date] 时间字符串
  /// [defaultDate] 默认DateTime，解析失败则返回此参数，选填
  /// [isUtc] 同DateTime isUtc
  static DateTime getDateTime(String date, {DateTime defaultDate, bool isUtc}) {
    DateTime dateTime = DateTime.tryParse(date);
    if (isUtc != null) {
      if (isUtc) {
        dateTime = dateTime.toUtc();
      } else {
        dateTime = dateTime.toLocal();
      }
    }
    return dateTime ?? defaultDate;
  }

  /// 基于毫秒值返回时间
  ///
  /// [milliseconds] 毫秒值
  /// [isUtc] 同DateTime isUtc
  static DateTime getDateTimeByMs(int milliseconds, {bool isUtc = false}) {
    return milliseconds == null ? null : DateTime.fromMillisecondsSinceEpoch(milliseconds, isUtc: isUtc);
  }

  /// 基于DateTime获取时间字符串
  ///
  /// [dateTime] 时间
  /// [dateFormat] 格式，默认yyyy-MM-dd HH:mm:ss
  /// [format] 自定义格式，选填
  /// [chinese] 是否中文
  /// [locale] 时区
  static String getDateFormatStrByDateTime(DateTime dateTime, {DateFormat dateFormat = DateFormat.NORMAL, String format, bool chinese = false, String locale = _DATE_LOCALE}) {
    if (TextUtil.isEmpty(format)) {
      format = chinese ? _zhDateFormats[dateFormat] : _dateFormats[dateFormat];
    }
    intl.DateFormat intlDateFormat = intl.DateFormat(format, locale);
    return intlDateFormat.format(dateTime);
  }

  /// 基于时间字符串获取DateTime
  ///
  /// [time] 时间字符串
  /// [dateFormat] 格式，默认yyyy-MM-dd HH:mm:ss
  /// [format] 自定义格式，选填
  /// [chinese] 是否中文
  /// [locale] 时区
  static DateTime getDateByTimeStr(String time, {DateFormat dateFormat = DateFormat.NORMAL, String format, bool chinese = false, String locale = _DATE_LOCALE}) {
    if (TextUtil.isEmpty(time)) return null;
    if (TextUtil.isEmpty(format)) {
      format = chinese ? _zhDateFormats[dateFormat] : _dateFormats[dateFormat];
    }
    intl.DateFormat intlDateFormat = intl.DateFormat(format, locale);
    return intlDateFormat.parse(time);
  }

  /// 获取当前时间所在区间
  ///
  /// [currentTime] 当前时间
  /// [intervalType] 间隔类型
  static List<DateTime> interval(DateTime currentTime, {DateIntervalType intervalType = DateIntervalType.day}) {
    DateTime startTime = currentTime;
    DateTime endTime = currentTime;
    switch (intervalType) {
      case DateIntervalType.day:
        startTime = DateTime(currentTime.year, currentTime.month, currentTime.day);
        endTime = DateTime(currentTime.year, currentTime.month, currentTime.day, 23, 59, 59);
        break;
      case DateIntervalType.week:
        int weekday = currentTime.weekday;
        startTime = DateTime(currentTime.year, currentTime.month, currentTime.day - weekday + 1);
        endTime = DateTime(currentTime.year, currentTime.month, currentTime.day + (7 - weekday), 23, 59, 59);
        break;
      case DateIntervalType.month:
        startTime = DateTime(currentTime.year, currentTime.month, 1);
        endTime = DateTime.fromMillisecondsSinceEpoch(DateTime(currentTime.year, currentTime.month + 1, 1).millisecondsSinceEpoch - 1000);
        break;
      case DateIntervalType.year:
        startTime = DateTime(currentTime.year);
        endTime = DateTime(currentTime.year, 12, 31, 23, 59, 59);
        break;
    }

    return [startTime, endTime];
  }
}
